package com.swak.wait;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executor;

import com.swak.reactivex.threads.Barrier;
import com.swak.reactivex.threads.WaitStrategy;
import com.swak.reactivex.threads.waitstrategy.YieldingWaitStrategy;

/**
 * 线程等待的测试.
 * 
 * @author 618lf
 */
public class ThreadWaitTest2 implements Executor {

	private Thread thread;
	// private Queue<Runnable> queue = new ArrayBlockingQueue<Runnable>(1024);
	private BlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(1024);
	private final Barrier barrier;
	// private WaitStrategy waitStrategy = new YieldingWaitStrategy();
	private WaitStrategy waitStrategy = new YieldingWaitStrategy();

	public ThreadWaitTest2() {
		thread = new Thread(this::run, "Thread.Wait");
		thread.start();
		this.barrier = () -> {
			return !queue.isEmpty() ? 0 : Long.MAX_VALUE;
		};
	}

	/**
	 * 有限等待
	 */
	private void run() {
		for (;;) {

			// wait for something
			try {
				waitStrategy.waitFor(barrier);
			} catch (Exception e) {
			}

			// do something
			Runnable run = queue.poll();
			if (run != null) {
				try {
					run.run();
				} catch (Exception e) {
				}
			}
		}
	}

	@Override
	public void execute(Runnable command) {
		queue.offer(command);
	}

	public static void main(String[] args) {
		ThreadWaitTest2 waitTest = new ThreadWaitTest2();
		waitTest.execute(() -> {
			System.out.println("run ");
		});
	}
}
